<template>
    <MountingPortal mountTo="#tipWidget" append>
        <div
            v-if="show"
            ref="mTooltip"
            :style="moveStyle"
            :class="`mouse-tooltip blur ${!noArrow ? arrowclass : 'no-arrow'} ${className}`"
        >
            <slot />
        </div>
    </MountingPortal>
</template>

<script>
export default {
    name: 'MTooltip',
    components: {},
    props: {
        show: {
            type: Boolean,
            default: false,
        },
        trigger: {
            type: String,
            default: 'hover',
        },
        target: {
            type: Object,
            default: null,
        },
        parent: {
            type: Object | String,
            default: null,
        },
        noArrow: {
            type: Boolean,
            default: false,
        },
        className: {
            type: String,
            default: '',
        },
    },
    data() {
        return {
            width: 0,
            height: 0,
            x: 0,
            y: 0,
            windowWidth: 0,
            windowHeight: 0,
            arrowclass: 'tooltip-left',
        }
    },
    computed: {
        moveStyle() {
            if (this.trigger == 'hover') {
                return {
                    transform: `translate(${this.x}px, ${this.y}px)`,
                }
            } else if (this.trigger == 'click') {
                return {
                    left: `${this.x}px`,
                    top: `${this.y}px`,
                    pointerEvents: 'unset',
                }
            } else {
                return {
                    transform: `translate(${this.x}px, ${this.y}px)`,
                }
            }
        },
    },
    mounted() {
        this.$nextTick(() => {
            // 确保DOM更新完成后再获取尺寸
            this.updateSize()
            this.updateWindowSize()
        })
        if (this.trigger == 'hover') window.addEventListener('mousemove', this.updateMousePosition)
        if (this.trigger == 'click') window.addEventListener('mousedown', this.updateMousePosition)
        window.addEventListener('resize', this.updateWindowSize)
        window.addEventListener('wheel', this.updateWheel)
    },
    beforeDestroy() {
        if (this.trigger == 'hover')
            window.removeEventListener('mousemove', this.updateMousePosition)
        if (this.trigger == 'click')
            window.removeEventListener('mousedown', this.updateMousePosition)
        window.removeEventListener('resize', this.updateWindowSize)
        window.removeEventListener('wheel', this.updateWheel)
    },
    methods: {
        updateMousePosition(event) {
            if (this.trigger == 'click') {
                const parent = this.$refs.mTooltip
                if (!parent?.contains(event.target)) {
                    this.$emit('update:show', false)
                } else {
                    return
                }
            }
            const mouseX = event.clientX
            const mouseY = event.clientY
            this.updateSize()
            if (mouseX >= this.windowWidth / 2) {
                this.x = mouseX - this.width
                this.arrowclass = 'tooltip-left'
            } else {
                this.x = mouseX
                this.arrowclass = 'tooltip-right'
            }

            this.y = mouseY - 40
        },
        updateWindowSize() {
            if (this.parent) {
                if (typeof this.parent == 'string') {
                    this.windowWidth = document.getElementById(this.parent).innerWidth
                    this.windowHeight = document.getElementById(this.parent).innerHeight
                } else {
                    this.windowWidth = this.parent.innerWidth
                    this.windowHeight = this.parent.innerHeight
                }
            } else {
                this.windowWidth = window.innerWidth
                this.windowHeight = window.innerHeight
            }
        },
        updateSize() {
            const el = this.$refs.mTooltip
            if (el) {
                this.width = el.offsetWidth
                this.height = el.offsetHeight
            }
        },
        updateWheel() {
            if (this.show) this.$emit('update:show', false)
        },
    },
}
</script>
<style lang="scss" scoped>
.mouse-tooltip {
    position: absolute;
    // transition: transform 0.1s ease;
    transform-origin: 0 0;

    // opacity: 0.8;
    padding: 6px;
    // border-radius: 8px;
    background-color: rgba(255, 255, 255, 0.7);
    // border: 1px solid #fff;
    border-radius: 4px;
    color: #222;
    white-space: nowrap;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
    pointer-events: none;
    backdrop-filter: blur(12px);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);

    &::before {
        position: absolute;
        top: 40px;
        margin-top: -8px;
        pointer-events: none;
        border: 8px solid transparent;
        background: transparent;
        content: '';
    }
    &.no-arrow::before {
        display: none;
    }
    &.tooltip-left {
        margin-left: -8px;
    }
    &.tooltip-right {
        margin-left: 8px;
    }
    &.tooltip-left::before {
        right: 0;
        margin-right: -16px;
        border-left-color: rgba(255, 255, 255, 0.8);
    }
    &.tooltip-right::before {
        left: 0;
        margin-left: -16px;
        border-right-color: rgba(255, 255, 255, 0.8);
    }
}
</style>
